﻿/*------------------------------------------------------------------------

GROUPRD.HPP v1.0.1

Copyright 楊志賢 CxxlMan, 2014
All Rights Reserved

------------------------------------------------------------------------*/

#if !defined(__GROUPRD_HPP_Cxxl3D)
#define __GROUPRD_HPP_Cxxl3D

#include <Sys\RenderUnit\SYSDDCLASSID.HPP>
#include <Sys\IREBDERPIPE.HPP>
#include <Sys\RENDERUNIT.HPP>


namespace Cxxl3D
{

class IGroupBridge;

class IGroupRD:public IRenderDatagram, public IRDpkg
{

  // 這裡須傳回 IRenderDatagram 的 "實作介面"，即被 cxxlCM_GetElement() 叫用的 InterfaceID
  CxxlMan::UNICODE_String cxxlFASTCALL GetRenderDatagramID() const
  {
    return IGroup_ClassID;
  }

  // 傳回 IRenderDatagram 的 "實作介面"
  virtual void *cxxlFASTCALL GetDefaultInterface()
  {
    return this;
  }

  // 取得 IRenderDatagram 列表， 給 render 單元叫用
  virtual CxxlMan::Smart_Ptr<CxxlMan::cxxlList<IRenderDatagram> > cxxlFASTCALL GetList() = 0;


protected:
  // 儲存容器藉此取得要永續存取的屬性資料
  // 延伸類別須以 virtual 的形式覆寫
  // 並且須呼叫上層類別的此函數
  virtual bool cxxlFASTCALL Ref(CxxlMan::Filter *F)
  {
    if(F != NULL && IRenderDatagram::Ref(F))
      return true;
    else
      return false;
  }


  // Constructor
  IGroupRD()
    :cxxlObject(CxxlMan::Spirit_Easy),
    CxxlMan::cxxlPreserve2(IGroup_ClassID), // 在建構時指定 ClassID
    IRDpkg(this)
  {
  }

  // Destructor
  virtual ~IGroupRD() = 0
  {
  }

public:

  // 加入一個 IRenderDatagram 物件，若是已 Crush 過了回覆 false
  virtual bool cxxlFASTCALL Add(const CxxlMan::Smart_Ptr<IRenderDatagram> &IRenderDatagram_Arg) = 0;

  // 移除一個 IRenderDatagram 物件，若是已 Crush 過了回覆 false
  virtual bool cxxlFASTCALL Del(const CxxlMan::Smart_Ptr<IRenderDatagram> &IRenderDatagram_Arg) = 0;

  // 清空，若是已 Crush 過了回覆 false
  virtual bool cxxlFASTCALL Clear() = 0;

  // 取得指定名稱的子 IGroupRD，找不到或是已 Crush 過了回覆 NULL
  virtual CxxlMan::Smart_Ptr<IGroupRD> cxxlFASTCALL GetChdGroup(const CxxlMan::UNICODE_String &Name) = 0;

  // 取得名稱
  virtual CxxlMan::UNICODE_String cxxlFASTCALL GetName() = 0;

  // 取得 IRenderDatagram 列表
  virtual CxxlMan::Smart_Ptr<CxxlMan::cxxlList<IRenderDatagram> > cxxlFASTCALL CopyList() = 0;


  // 清除除了已存在的 IRenderDatagram 列表外的所有資料，之後就不能再執行增刪和永續儲存的功能
  virtual void cxxlFASTCALL Crush() = 0;

  // 清除除了已存在的 IRenderDatagram 列表外的所有資料，包含子孫 IGroupRD，之後就不能再執行增刪和永續儲存的功能
  virtual void cxxlFASTCALL CrushAll() = 0;


  // 從永存資料產生 IGroupRD 物件
  // 失敗傳回 NULL
  static CxxlMan::Smart_Ptr<IGroupRD> cxxlFASTCALL Create(const CxxlMan::UNICODE_String &BackupName, const CxxlMan::Smart_Ptr<CxxlMan::IcxxlStorage> &IcxxlStorage_Arg)
  {
    CxxlMan::Smart_Ptr<cxxlPreserve2> cxxlPreserve2_Ptr(NULL);
    CxxlMan::REGENERARETURN_TYPE rt = cxxlCM_Regenera(cxxlPreserve2_Ptr, BackupName, IcxxlStorage_Arg, true);

    if(rt == CxxlMan::Regenera_Success)
      return CxxlMan::Smart_Cast<IGroupRD>(cxxlPreserve2_Ptr);
    else
      return NULL;
  }

  // 建立 IGroupRD 物件，須指定一個名稱，失敗傳回 NULL
  static CxxlMan::Smart_Ptr<IGroupRD> cxxlFASTCALL Create(const CxxlMan::UNICODE_String &Name)
  {
    return CxxlMan::Smart_Cast<IGroupRD>( CxxlMan::cxxlCM_GetElement(IGroup_ClassID, IRenderDatagram_Group, (void *)&Name) );
  }

  friend class CxxlMan::IcxxlStorage;          // Preserve2 元件須加上這個
  friend class CxxlMan::Smart_Ptr<IGroupRD>;  // Preserve2 元件須加上這個
  friend class IGroupBridge;
};

// 提供給 render 單元執行 IGroupRD::GetList() 的權力
class IGroupBridge
{
protected:
  // 取得 IRenderDatagram 列表， 給 render 單元叫用
  CxxlMan::Smart_Ptr<CxxlMan::cxxlList<IRenderDatagram> > cxxlFASTCALL GetList(const CxxlMan::Smart_Ptr<IGroupRD> &IGroupRD_Arg)
  {
    return IGroupRD_Arg->GetList();
  }
};

}   /* namespace Cxxl3D */
#endif